using DaoHang.Components;
using DaoHang.Data;
using DaoHang.Services;
using DaoHang.Models;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.HttpOverrides;
using System.Security.Claims;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Server;
using System.Collections.Concurrent;
using System.IO;
using System.Security.AccessControl;

namespace DaoHang
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // 从配置文件中获取服务器配置
            var serverConfig = builder.Configuration.GetSection("Server");
            var host = serverConfig["Host"] ?? "127.0.0.1";
            var basePort = int.Parse(serverConfig["Port"] ?? "5000");
            var adminRoute = serverConfig["AdminRoute"] ?? "admin";
            var useHttps = bool.Parse(serverConfig["UseHttps"] ?? "false");
            var behindProxy = bool.Parse(serverConfig["BehindProxy"] ?? "false");
            
            // 配置反向代理支持
            if (behindProxy)
            {
                builder.Services.Configure<ForwardedHeadersOptions>(options =>
                {
                    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | 
                                              ForwardedHeaders.XForwardedProto | 
                                              ForwardedHeaders.XForwardedHost;
                    // 信任所有代理（在生产环境中应该限制为已知的代理IP）
                    options.KnownNetworks.Clear();
                    options.KnownProxies.Clear();
                    // 处理原始主机头
                    options.ForwardLimit = null;
                    options.RequireHeaderSymmetry = false;
                    
                    // 优化Host头处理
                    options.OriginalHostHeaderName = "X-Original-Host";
                    options.OriginalProtoHeaderName = "X-Original-Proto";
                    
                    // 处理端口转发
                    options.AllowedHosts.Clear(); // 允许所有主机
                });
                
                // 配置Blazor Server的基础URL，确保在反向代理环境下正确工作
                builder.Services.Configure<Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature>(options => { });
                Console.WriteLine("🔧 反向代理模式：已配置转发头处理");
            }
            
            // 设置URL（仅HTTP模式用于反向代理）
            // 强制配置URL，不检查环境变量（防止被launchSettings.json覆盖）
            if (behindProxy)
            {
                // 反向代理模式：强制只使用HTTP，忽略任何其他配置
                builder.WebHost.UseUrls($"http://{host}:{basePort}");
                Console.WriteLine($"🔧 反向代理模式：强制设置 URL http://{host}:{basePort}");
            }
            else if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ASPNETCORE_URLS")))
            {
                if (useHttps)
                {
                    var httpsPort = basePort + 1;
                    builder.WebHost.UseUrls(
                        $"http://{host}:{basePort}",
                        $"https://{host}:{httpsPort}"
                    );
                }
                else
                {
                    builder.WebHost.UseUrls($"http://{host}:{basePort}");
                }
            }

            // 配置日志
            builder.Logging.ClearProviders();
            builder.Logging.AddConsole();
            builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Warning);
            builder.Logging.AddFilter("DaoHang.Services", Microsoft.Extensions.Logging.LogLevel.Information);
            builder.Logging.AddDbLogger(builder.Services);

            // 仅在不使用反向代理且启用HTTPS时配置HTTPS重定向
            if (useHttps && !behindProxy)
            {
                builder.Services.AddHttpsRedirection(options =>
                {
                    options.HttpsPort = basePort + 1;
                });
            }
            else if (behindProxy)
            {
                // 反向代理模式下完全禁用HTTPS重定向
                Console.WriteLine("🔧 反向代理模式：已禁用HTTPS重定向");
            }

            // 添加Razor组件和服务
            builder.Services.AddRazorComponents()
                .AddInteractiveServerComponents();

            // 配置SQLite数据库
            var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? "Data Source=daohang.db";
            builder.Services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlite(connectionString));

            // 注册业务服务
            builder.Services.AddScoped<IWebsiteService, WebsiteService>();
            builder.Services.AddScoped<ICategoryService, CategoryService>();
            builder.Services.AddScoped<IUserService, UserService>();
            builder.Services.AddScoped<ISiteSettingsService, SiteSettingsService>();
            builder.Services.AddScoped<ILogService, LightLogService>();
            builder.Services.AddScoped<IWebsiteInfoService, WebsiteInfoService>();
            builder.Services.AddScoped<IAliCloudAIService, AliCloudAIService>();
            builder.Services.AddScoped<IDataExportService, DataExportService>();
            builder.Services.AddScoped<IDataSeedService, DataSeedService>();
            builder.Services.AddScoped<IIconService, IconService>();

            // 注册HttpClient和HttpContextAccessor
            builder.Services.AddHttpClient<IWebsiteInfoService, WebsiteInfoService>();
            builder.Services.AddHttpClient<IAliCloudAIService, AliCloudAIService>();
            builder.Services.AddHttpClient<IIconService, IconService>();
            builder.Services.AddHttpContextAccessor();

            // 添加身份验证服务
            builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
                {
                    options.LoginPath = $"/{adminRoute}/login";
                    options.LogoutPath = $"/{adminRoute}/logout";
                    options.AccessDeniedPath = $"/{adminRoute}/access-denied";
                    options.Cookie.Name = ".AspNetCore.Cookies";
                    options.Cookie.HttpOnly = true;
                    options.Cookie.SameSite = SameSiteMode.Lax;
                    
                    if (behindProxy)
                    {
                        // 反向代理模式下的Cookie配置
                        options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
                        // 不设置特定域名，让Cookie适应当前域名
                        options.Cookie.Domain = null;
                        Console.WriteLine("🔧 反向代理模式：Cookie配置已优化");
                    }
                    else
                    {
                        // 直接访问模式下的Cookie配置
                        options.Cookie.SecurePolicy = useHttps ? CookieSecurePolicy.Always : CookieSecurePolicy.SameAsRequest;
                    }
                });

            // 添加Blazor认证状态提供器
            builder.Services.AddScoped<AuthenticationStateProvider, ServerAuthenticationStateProvider>();

            // 反向代理模式下的特殊配置
            if (behindProxy)
            {
                // 配置Blazor Server在反向代理环境下的行为
                builder.Services.Configure<Microsoft.AspNetCore.Components.Server.CircuitOptions>(options =>
                {
                    options.DetailedErrors = builder.Environment.IsDevelopment();
                });
                
                Console.WriteLine("🔧 反向代理模式：已配置Blazor Server选项");
            }

            // 构建应用
            var app = builder.Build();

            // 配置反向代理中间件（必须在最前面）
            if (behindProxy)
            {
                app.UseForwardedHeaders();
            }

            // 配置中间件
            if (!app.Environment.IsDevelopment())
            {
                app.UseExceptionHandler("/Error");
                // 反向代理模式下不使用HSTS，由反向代理服务器处理
                if (!behindProxy && useHttps)
                {
                    app.UseHsts();
                }
            }
            else
            {
                app.UseDeveloperExceptionPage();
            }

            // 仅在不使用反向代理且启用HTTPS时使用HTTPS重定向
            if (useHttps && !behindProxy)
            {
                app.UseHttpsRedirection();
                Console.WriteLine("🔧 直接访问模式：已启用HTTPS重定向");
            }
            else if (behindProxy)
            {
                Console.WriteLine("🔧 反向代理模式：跳过HTTPS重定向，由反向代理处理");
            }

            app.UseStaticFiles();
            app.UseAntiforgery();
            app.UseAuthentication();
            app.UseAuthorization();

            // 添加登录API端点
            app.MapGet("/api/auth/login", async (string credentials, IUserService userService, ILogService logService, HttpContext context) =>
            {
                var loginLogger = context.RequestServices.GetRequiredService<ILogger<Program>>();
                string? username = null;
                
                try
                {
                    // 解码凭据
                    var decodedCredentials = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(credentials));
                    var parts = decodedCredentials.Split(':');
                    
                    if (parts.Length != 2)
                    {
                        await logService.LogWarningAsync("登录失败：凭据格式无效", "Security", null);
                        return Results.Redirect($"/{adminRoute}/login?error=invalid");
                    }

                    username = parts[0];
                    var password = parts[1];

                    // 验证用户
                    var isValid = await userService.ValidateUserAsync(username, password);
                    
                    if (isValid)
                    {
                        var claims = new[]
                        {
                            new Claim(ClaimTypes.Name, username),
                            new Claim(ClaimTypes.Role, "Admin")
                        };

                        var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
                        var principal = new ClaimsPrincipal(identity);

                        await context.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
                        await logService.LogInformationAsync($"用户 {username} 登录成功", "Security", username);
                        return Results.Redirect($"/{adminRoute}");
                    }
                    else
                    {
                        await logService.LogWarningAsync($"用户 {username} 登录失败：用户名或密码错误", "Security", username);
                        return Results.Redirect($"/{adminRoute}/login?error=invalid");
                    }
                }
                catch (Exception ex)
                {
                    loginLogger.LogError(ex, "登录过程中发生错误");
                    await logService.LogErrorAsync($"登录过程中发生异常", ex, "Security", username);
                    return Results.Redirect($"/{adminRoute}/login?error=server");
                }
            });

            // 添加登出API端点
            app.MapGet("/api/auth/logout", async (ILogService logService, HttpContext context) =>
            {
                var username = context.User?.Identity?.Name ?? "未知用户";
                
                try
                {
                    await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
                    await logService.LogInformationAsync($"用户 {username} 退出登录", "Security", username);
                    return Results.Redirect("/");
                }
                catch (Exception ex)
                {
                    await logService.LogErrorAsync($"用户 {username} 退出登录时发生异常", ex, "Security", username);
                    return Results.Redirect("/");
                }
            });

            // 添加Razor组件端点
            app.MapRazorComponents<App>()
                .AddInteractiveServerRenderMode();

            // 初始化数据库
            await InitializeDatabaseAsync(app, adminRoute);

            // 打印启动信息
            _ = PrintStartupInfoAsync(app, basePort, basePort + 1, adminRoute);

            // 启动应用
            await app.RunAsync();
        }

        /// <summary>
        /// 初始化数据库
        /// </summary>
        private static async Task InitializeDatabaseAsync(WebApplication app, string adminRoute)
        {
            using var scope = app.Services.CreateScope();
                var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
                var userService = scope.ServiceProvider.GetRequiredService<IUserService>();
                var logService = scope.ServiceProvider.GetRequiredService<ILogService>();
                var dataSeedService = scope.ServiceProvider.GetRequiredService<IDataSeedService>();
            var siteSettingsService = scope.ServiceProvider.GetRequiredService<ISiteSettingsService>();
            var iconService = scope.ServiceProvider.GetRequiredService<IIconService>();
            var configuration = scope.ServiceProvider.GetRequiredService<IConfiguration>();
            
            try
            {
                // 获取数据库连接字符串并检查路径
                var connectionString = configuration.GetConnectionString("DefaultConnection") ?? "Data Source=daohang.db";
                await EnsureDatabasePathExistsAsync(connectionString, logService);
                
                // 创建数据库并初始化必要数据
                    context.Database.EnsureCreated();

                    // 确保存在默认管理员账号
                    var hasAdmin = await userService.HasAdminUserAsync();
                    if (!hasAdmin)
                    {
                        await userService.CreateAdminUserAsync("admin", "admin");
                    }

                // 初始化默认数据
                    await dataSeedService.SeedAllDefaultDataAsync();

                // 生成默认图标文件
                await iconService.GenerateDefaultIconAsync();
                await logService.LogInformationAsync("默认图标文件已生成", "System");

                // 更新网站设置中的管理路由
                var siteSettings = await siteSettingsService.GetSiteSettingsAsync();
                siteSettings.AdminRoute = adminRoute;
                await siteSettingsService.SaveSiteSettingsAsync(siteSettings);
                
                // 记录启动完成日志
                await logService.LogInformationAsync("系统启动完成", "System");
                }
                catch (Exception ex)
                {
                    await logService.LogErrorAsync("数据库初始化失败", ex, "Database");
                
                    if (!app.Environment.IsDevelopment())
                    {
                        throw;
                }
            }
        }

        /// <summary>
        /// 确保数据库路径存在并有正确的权限
        /// </summary>
        private static async Task EnsureDatabasePathExistsAsync(string connectionString, ILogService logService)
        {
            try
            {
                // 从连接字符串中提取数据库文件路径
                var dbPath = ExtractDatabasePath(connectionString);
                if (string.IsNullOrEmpty(dbPath))
                {
                    await logService.LogWarningAsync("无法从连接字符串中提取数据库路径", "Database");
                    return;
                }

                // 获取数据库文件目录
                var dbDirectory = Path.GetDirectoryName(dbPath);
                if (!string.IsNullOrEmpty(dbDirectory) && !Directory.Exists(dbDirectory))
                {
                    await logService.LogInformationAsync($"创建数据库目录: {dbDirectory}", "Database");
                    Directory.CreateDirectory(dbDirectory);
                    
                    // 在Linux环境下设置目录权限
                    if (OperatingSystem.IsLinux())
                    {
                        try
                        {
                            // 尝试设置目录权限 (755)
                            File.SetUnixFileMode(dbDirectory, UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute | 
                                                            UnixFileMode.GroupRead | UnixFileMode.GroupExecute | 
                                                            UnixFileMode.OtherRead | UnixFileMode.OtherExecute);
                            await logService.LogInformationAsync($"设置数据库目录权限: {dbDirectory}", "Database");
                        }
                        catch (Exception ex)
                        {
                            await logService.LogWarningAsync($"设置目录权限失败: {ex.Message}", "Database");
                        }
                    }
                }

                // 检查数据库文件是否存在，如果不存在则尝试创建空文件
                if (!File.Exists(dbPath))
                {
                    await logService.LogInformationAsync($"创建数据库文件: {dbPath}", "Database");
                    
                    // 尝试创建空的数据库文件以测试权限
                    await File.WriteAllTextAsync(dbPath, "");
                    
                    // 在Linux环境下设置文件权限
                    if (OperatingSystem.IsLinux())
                    {
                        try
                        {
                            // 设置文件权限 (644)
                            File.SetUnixFileMode(dbPath, UnixFileMode.UserRead | UnixFileMode.UserWrite | 
                                                        UnixFileMode.GroupRead | UnixFileMode.OtherRead);
                            await logService.LogInformationAsync($"设置数据库文件权限: {dbPath}", "Database");
                        }
                        catch (Exception ex)
                        {
                            await logService.LogWarningAsync($"设置文件权限失败: {ex.Message}", "Database");
                        }
                    }
                }
                else
                {
                    // 检查现有文件的访问权限
                    try
                    {
                        // 尝试打开文件检查权限
                        using var fileStream = File.Open(dbPath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                        await logService.LogInformationAsync($"数据库文件已存在且可访问: {dbPath}", "Database");
                    }
                    catch (UnauthorizedAccessException)
                    {
                        throw new UnauthorizedAccessException($"无法访问数据库文件，权限不足: {dbPath}");
                    }
                    catch (IOException ex)
                    {
                        await logService.LogWarningAsync($"数据库文件访问检查警告: {ex.Message}", "Database");
                    }
                }
            }
            catch (Exception ex)
            {
                await logService.LogErrorAsync($"数据库路径检查失败: {ex.Message}", ex, "Database");
                throw;
            }
        }

        /// <summary>
        /// 从连接字符串中提取数据库文件路径
        /// </summary>
        private static string ExtractDatabasePath(string connectionString)
        {
            try
            {
                // 常见的SQLite连接字符串格式：
                // "Data Source=path/to/database.db"
                // "DataSource=path/to/database.db"
                var patterns = new[] { "Data Source=", "DataSource=" };
                
                foreach (var pattern in patterns)
                {
                    var index = connectionString.IndexOf(pattern, StringComparison.OrdinalIgnoreCase);
                    if (index >= 0)
                    {
                        var pathStart = index + pattern.Length;
                        var pathEnd = connectionString.IndexOfAny(new[] { ';', '\r', '\n' }, pathStart);
                        
                        var dbPath = pathEnd > 0 
                            ? connectionString.Substring(pathStart, pathEnd - pathStart).Trim()
                            : connectionString.Substring(pathStart).Trim();
                            
                        return dbPath;
                    }
                }
                
                return string.Empty;
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 打印启动信息
        /// </summary>
        private static async Task PrintStartupInfoAsync(WebApplication app, int httpPort, int httpsPort, string adminRoute)
            {
                await Task.Delay(1000); // 等待1秒让服务器完全启动
                
                try
                {
                var configuration = app.Services.GetRequiredService<IConfiguration>();
                var behindProxy = bool.Parse(configuration["Server:BehindProxy"] ?? "false");
                var useHttps = bool.Parse(configuration["Server:UseHttps"] ?? "false");
                    
                    Console.WriteLine("=".PadRight(60, '='));
                    Console.WriteLine("🚀 DaoHang 导航网站系统启动成功！");
                    Console.WriteLine("=".PadRight(60, '='));
                    
                if (behindProxy)
                {
                    // 反向代理模式
                    Console.WriteLine($"🌐 内部HTTP地址: http://localhost:{httpPort}");
                    Console.WriteLine($"🎯 反向代理模式: 已启用");
                    Console.WriteLine($"🔒 HTTPS处理: 由反向代理服务器处理");
                    
                    // 显示局域网访问地址（仅用于内部测试）
                    var localIp = GetLocalIPAddress();
                    if (!string.IsNullOrEmpty(localIp))
                    {
                        Console.WriteLine($"🔧 内部测试地址: http://{localIp}:{httpPort}");
                    }
                    
                    Console.WriteLine("=".PadRight(60, '='));
                    Console.WriteLine($"✅ 管理后台路由: /{adminRoute}");
                    Console.WriteLine($"💡 访问方式: 通过反向代理域名访问");
                }
                else
                {
                    // 直接访问模式
                    Console.WriteLine($"🌐 HTTP 地址: http://localhost:{httpPort}");
                    if (useHttps)
                    {
                        Console.WriteLine($"🌐 HTTPS 地址: https://localhost:{httpsPort}");
                    }
                    
                    // 显示局域网访问地址
                                var localIp = GetLocalIPAddress();
                                if (!string.IsNullOrEmpty(localIp))
                                {
                        Console.WriteLine($"🌐 局域网 HTTP 地址: http://{localIp}:{httpPort}");
                        if (useHttps)
                        {
                            Console.WriteLine($"🌐 局域网 HTTPS 地址: https://{localIp}:{httpsPort}");
                        }
                    }
                    
                    Console.WriteLine("=".PadRight(60, '='));
                    Console.WriteLine($"✅ 后台管理地址: http://localhost:{httpPort}/{adminRoute}");
                    if (useHttps)
                    {
                        Console.WriteLine($"✅ 后台管理地址(HTTPS): https://localhost:{httpsPort}/{adminRoute}");
                    }
                }
                
                Console.WriteLine("=".PadRight(60, '='));
                
                // 打印数据库状态
                using (var scope = app.Services.CreateScope())
                {
                    try
                    {
                        var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
                        var canConnect = await dbContext.Database.CanConnectAsync();
                        Console.WriteLine(canConnect 
                            ? "✅ 数据库连接正常" 
                            : "❌ 数据库连接失败，请检查配置");
                    }
                    catch
                    {
                        Console.WriteLine("❌ 数据库连接失败，请检查配置");
                    }
                }
                Console.WriteLine("=".PadRight(60, '='));
            }
            catch
            {
                // 忽略启动信息打印异常
            }
        }

        /// <summary>
        /// 获取本机IP地址
        /// </summary>
        private static string GetLocalIPAddress()
        {
            try
            {
                var host = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());
                foreach (var ip in host.AddressList)
                {
                    if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        return ip.ToString();
                    }
                }
            }
            catch
            {
                // 忽略错误
            }
            return string.Empty;
        }
    }

    // 数据库日志提供程序扩展
    public static class DbLoggerExtensions
    {
        public static ILoggingBuilder AddDbLogger(this ILoggingBuilder builder, IServiceCollection services)
        {
            services.AddSingleton<DbLoggerProvider>();
            builder.AddProvider(services.BuildServiceProvider().GetRequiredService<DbLoggerProvider>());
            return builder;
        }
    }

    // 数据库日志提供程序
    public class DbLoggerProvider : ILoggerProvider
    {
        private readonly ConcurrentQueue<LogEntry> _pendingLogs = new();
        private readonly Timer _timer;
        private readonly IServiceProvider _serviceProvider;

        public DbLoggerProvider(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
            _timer = new Timer(FlushLogs, null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5));
        }

        public ILogger CreateLogger(string categoryName)
        {
            return new DbLogger(categoryName, this);
        }

        public void AddLog(string category, Microsoft.Extensions.Logging.LogLevel logLevel, string message, Exception? exception = null)
        {
            var entry = new LogEntry
            {
                Category = category,
                Level = logLevel.ToString(),
                Message = message,
                Exception = exception?.ToString(),
                Timestamp = DateTime.Now
            };

            _pendingLogs.Enqueue(entry);
        }

        private void FlushLogs(object? state)
        {
            if (_pendingLogs.IsEmpty) return;

            try
            {
                using var scope = _serviceProvider.CreateScope();
                var logService = scope.ServiceProvider.GetRequiredService<ILogService>();

                while (_pendingLogs.TryDequeue(out var log))
                {
                    // 使用日志服务记录日志
                    Task.Run(async () =>
                    {
                        try
                        {
                            switch (log.Level)
                            {
                                case "Information":
                                    await logService.LogInformationAsync(log.Message, log.Category);
                                    break;
                                case "Warning":
                                    await logService.LogWarningAsync(log.Message, log.Category);
                                    break;
                                case "Error":
                                case "Critical":
                                    await logService.LogErrorAsync(log.Message, log.Exception != null ? new Exception(log.Exception) : null, log.Category);
                                    break;
                                case "Debug":
                                    await logService.LogDebugAsync(log.Message, log.Category);
                                    break;
                                case "Trace":
                                    await logService.LogTraceAsync(log.Message, log.Category);
                                    break;
                            }
                        }
                        catch
                        {
                            // 忽略日志写入错误
                        }
                    });
                }
            }
            catch
            {
                // 忽略日志刷新错误
            }
        }

        public void Dispose()
        {
            _timer?.Dispose();
        }

        private class DbLogger : ILogger
        {
            private readonly string _categoryName;
            private readonly DbLoggerProvider _provider;

            public DbLogger(string categoryName, DbLoggerProvider provider)
            {
                _categoryName = categoryName;
                _provider = provider;
            }

            public IDisposable? BeginScope<TState>(TState state) where TState : notnull => null;

            public bool IsEnabled(Microsoft.Extensions.Logging.LogLevel logLevel) => logLevel != Microsoft.Extensions.Logging.LogLevel.None;

            public void Log<TState>(Microsoft.Extensions.Logging.LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
            {
                if (!IsEnabled(logLevel)) return;

                var message = formatter(state, exception);
                _provider.AddLog(_categoryName, logLevel, message, exception);
            }
        }
    }
}
